package main

import (
	"fmt"
	"sync"
)

type MyCache struct {
	cache sync.Map
	mu    sync.Mutex
}

func (c *MyCache) getData(key string) (interface{}, bool) {
	// 尝试从缓存中读取
	var value interface{}
	value, ok := c.cache.Load(key)
	if value != nil && ok {
		c.cache.LoadOrStore(key, nil) // 使用LoadOrStore来触发加载（这里只是为了检查是否存在，所以value设为nil）
		c.cache.Load(key)             // 再次加载以获取实际值
		c.cache.Store(key, value)     // 重新存储以确保map中有值（如果需要的话，这个步骤可以优化掉，因为我们只是检查存在性）
		c.cache.Range(func(k, v interface{}) bool {
			if k == key {
				value = v
				return false // 找到后停止遍历
			}
			return true
		})
		if value != nil {
			return value, true
		}
	}

	// 缓存中没有，加锁后从"数据库"（这里模拟）中加载
	c.mu.Lock()
	defer c.mu.Unlock()

	// 双重检查锁定（Double-Checked Locking），以防在获取锁之前另一个goroutine已经添加了数据
	v, ok := c.cache.Load(key)
	if v == nil && !ok {
		value = "you are so intelligent"
		c.cache.Store(key, value)
	} else {
		// 另一个goroutine可能已经添加了数据，所以再次从缓存中加载
		c.cache.Range(func(k, v interface{}) bool {
			if k == key {
				value = v
				return false
			}
			return true
		})
	}

	return value, value != nil
}

func main() {
	cache := &MyCache{}

	// 测试获取数据
	if val, found := cache.getData("testKey"); found {
		fmt.Println("Found value:", val)
	} else {
		fmt.Println("Value not found")
	}

	// 再次测试，这次值应该已经缓存了
	if val, found := cache.getData("testKey"); found {
		fmt.Println("Found value:", val)
	} else {
		fmt.Println("Value not found")
	}
}
